package org.durcframework.core.controller;

import java.beans.PropertyEditor;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.durcframework.core.DefaultMessageResult;
import org.durcframework.core.MessageResult;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;

/**
 * 提供基础能力的Controller,如果一个Controller具备简单功能可以继承这个类
 * @author hc.tang
 * 2015-2-28
 */
public abstract class BaseController {
	// 此字段的用处见render.jsp
	// 加上BindingResult.MODEL_KEY_PREFIX前缀,返回ModelAndView对象时不会再次进入initBinder()方法中.
	// 详见org.springframework.web.method.annotation.ModelFactory.isBindingCandidate(String, Object)
	public static final String DEF_MODEL_NAME = BindingResult.MODEL_KEY_PREFIX + "renderData";
	// 默认视图render.jsp
	private static final String DEF_VIEW_NAME = "render";
	
	private static ThreadLocal<PropertyEditor> propertyEditorStore = new ThreadLocal<PropertyEditor>();
	
	public HttpServletRequest getRequest() {
		return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
	}
	
	public HttpSession getSession() {
		return getRequest().getSession();
	}
	
	@InitBinder
    protected void initBinder(WebDataBinder binder) {
		this.initCustomEditor(binder);
    }
	
	protected void initCustomEditor(WebDataBinder binder) {
		// 默认时间转换
		PropertyEditor propertyEditor = propertyEditorStore.get();
		if(propertyEditor == null) {
			DateFormat dateFormat = new SimpleDateFormat(getDateFormatPattern());
			propertyEditor = new CustomDateEditor(dateFormat, true);
			propertyEditorStore.set(propertyEditor);
		}
		
		binder.registerCustomEditor(Date.class, propertyEditor);
	}
	
	protected String getDateFormatPattern() {
		return "yyyy-MM-dd";
	}
	
	@ExceptionHandler
	protected Object exceptionHandler(HttpServletRequest request,
			HttpServletResponse response,
			Exception e) {
		return this.getErrorView(e);
    }
	
	protected ModelAndView getErrorView(Exception e) {
		return this.render(this.error(e.getMessage()));
	}
	
	/**
	 * 返回成功的视图
	 * @return 默认返回DefaultMessageResult对象,可以重写getMessageResult()方法返回自定义的MessageResult
	 */
	public MessageResult success() {
		MessageResult msgResult = getMessageResult();
		msgResult.setSuccess(true);
		return msgResult;
	}
	
	/**
	 * 返回成功
	 * @param message
	 * @return 默认返回DefaultMessageResult对象,可以重写getMessageResult()方法返回自定义的MessageResult
	 */
	public MessageResult success(String message) {
		MessageResult msgResult = getMessageResult();
		msgResult.setSuccess(true);
		msgResult.setMessage(message);
		return msgResult;
	}
	
	/**
	 * 返回错误的视图
	 * @param errorMsg 错误信息
	 * @return 默认返回DefaultMessageResult对象,可以重写getMessageResult()方法返回自定义的MessageResult
	 */
	public MessageResult error(String errorMsg) {
		MessageResult msgResult = getMessageResult();
		msgResult.setSuccess(false);
		msgResult.setMessage(errorMsg);
		return msgResult;
	}
	
	/**
	 * 返回错误信息
	 * @param errorMsg 错误信息
	 * @param errorMsgs 更多错误信息
	 * @return 默认返回DefaultMessageResult对象,可以重写getMessageResult()方法返回自定义的MessageResult
	 */
	public MessageResult error(String errorMsg,List<String> errorMsgs) {
		MessageResult msgResult = error(errorMsg);
		msgResult.setMessages(errorMsgs);
		return msgResult;
	}
	
	//--------------- for view ---------------
	
	public ModelAndView successView() {
		return this.render(this.success());
	}
	
	public ModelAndView successView(String message) {
		return this.render(this.success(message));
	}
	
	public ModelAndView errorView(String errorMsg,List<String> errorMsgs) {
		return this.render(this.error(errorMsg, errorMsgs));
	}
	
	public ModelAndView errorView(String errorMsg) {
		return this.render(this.error(errorMsg));
	}
	
	public ModelAndView render(Object modelObject) {
		return this.render(this.getDefaultView(), modelObject);
	}
	
	public ModelAndView render(String viewName, Object modelObject) {
		return this.render(viewName, DEF_MODEL_NAME, modelObject);
	}
	
	public ModelAndView render(String viewName, String modelName, Object modelObject) {
		return new ModelAndView(viewName, modelName, modelObject);
	}
	
	protected String getDefaultView() {
		return DEF_VIEW_NAME;
	}
	
	/**
	 * 返回默认的消息实现类,可覆盖此方法返回自定义的消息实现类
	 * @return
	 */
	protected MessageResult getMessageResult() {
		return new DefaultMessageResult();
	}
}
